全局中间件之 ValidatePostSize
简介
上一章,我们了解了 第一个 中间件 CheckForMaintenanceMode
的作用,知道了此中间件就是判断我们的应用是否处于 维护模式。
这一章,我们我们来看 第二个 中间件 ValidatePostSize
。
从字面上的意思,我们大致知道与 验证 POST 数据大小 有关
其根本作用:拦截 POST 数据过大的异常,通过 PHP 异常处理机制,向请求方抛出 413 HTTP 异常。
ValidatePostSize
中的 handle 方法
前面,我们讲过,中间件作用的实现方式是通过执行中间件的 handle 方法来过滤 request 的。
handle 方法如下:
public function handle($request, Closure $next)
{
// $max 是 int 类型,单位字节。
$max = $this->getPostMaxSize();
// 通过对比头信息 CONTENT_LENGTH(POST 数据长度,单位字节),来判断是否抛出 PostTooLargeException 异常
if ($max > 0 && $request->server('CONTENT_LENGTH') > $max) {
throw new PostTooLargeException;
}
return $next($request);
}
进一步剖析讲解:首先通过 $this->getPostMaxSize()
获取 php.ini
中 post_max_size
设定的值,赋值给 $max
。然后对比 CONTENT_LENGTH
头信息记录的 post 请求长度,决定是否抛出异常。
- 关于
$this->getPostMaxSize()
:
protected function getPostMaxSize()
{
// 首先判断 post_max_size 设定的值有没有单位,没有则返回其值
if (is_numeric($postMaxSize = ini_get('post_max_size'))) {
return (int) $postMaxSize;
}
// 有单位时,截取单位,并转换为大写。
$metric = strtoupper(substr($postMaxSize, -1));
$postMaxSize = (int) $postMaxSize;
// 通过字节大写换算,将 post_max_size 设定的值转为字节单位(B)
switch ($metric) {
case 'K':
return $postMaxSize * 1024;
case 'M':
return $postMaxSize * 1048576;
case 'G':
return $postMaxSize * 1073741824;
default:
return $postMaxSize;
}
}
通过上面我们知道,如果在
php.ini
中设定 post_max_size 时,不想带单位,一定要以 字节(B) 的大小进行设置。即字节(B)可以省略。
例如: 设定 post_max_size 为 10M,可以有如下几种方式
post_max_size = 10M
post_max_size = 10m
post_max_size = 10485760
附录:
当我们上传大文件或者大数据时,仅仅设置 post_max_size 是不够的。
搭配 Nginx 完整设置如下
- 首先设置 Nginx 中的 conf。添加如下内容
# 1024m 代表 post 数据最大 1个G,根据情况自行设定
client_max_body_size 1204m;
如果想在全部 nginx 服务上实现大文件上传,就在 http 内设定 client_max_body_size
如果仅想指定一个 server 服务上实现大文件上传,就在指定的 server 内设定 client_max_body_size
- 其次,修改
php.ini
; 最大 POST 数据大小
post_max_size = 8M
; 上传最大文件大小
upload_max_filesize = 2M
; PHP 运行期间分配的最大内存
memory_limit = 128M
; GET/POST/COOKIE 上传后,PHP 分配的最大变量数
max_input_vars = 1000
以上,根据文件上传和数据上传情况,自行调整